#!/usr/bin/env python3
# -*- coding: utf-8 -*-
""" 分拣模拟系统核心逻辑模块
"""
import random
from typing import List, Dict, Any
from datetime import datetime

# 使用统一的日志配置
from fastapiApp.setting.logger_config import get_simulation_logger

logger = get_simulation_logger()

class SortingSimulation:
    """分拣模拟系统类，处理产品的生产、分拣和出库逻辑"""

    """初始化分拣模拟系统"""
    def __init__(self, product_types_count: int = 8, transfer_station_size: int = 15):
        self.product_types_count = product_types_count  # 产品种类数量
        self.transfer_station_size = transfer_station_size  # 中转站库位数量

        # 系统状态
        self.state = {
            "product_types": [],  # 产品类型列表
            "product_colors": {},  # 产品颜色映射
            "production": [],  # 当前生产的产品
            "production_AGV1": [],  # 产线AGV1产品
            "sorting_station": [],  # 分拣台的产品
            "sorting_AGV": [],  # 分拣AGV产品
            "transfer_station": [],  # 中转站的产品
            "flip_station": [],  # 翻转台的产品
            "flip_AGV": [],  # 翻转AGV产品
            "shipped_products": [],  # 已出库的产品
            "logs": [],  # 操作日志
            "is_auto_running": False,  # 是否自动运行
            "is_re_sorting": False,  # 是否正在重新分拣
            "re_sort_count": 0,  # 重新分拣次数统计
            "product_generation_mode": "random",  # 产品生成模式: random(随机) 或 sequence(顺序)
            "sequence_index": 0  # 顺序生成的当前索引
        }

        self.init_simulation()

    """初始化模拟系统"""
    def init_simulation(self) -> None:
        # 初始化产品类型和颜色
        self._init_product_types()
        # 初始化中转站
        self.state["transfer_station"] = [None] * self.transfer_station_size
        # 添加初始化日志
        self._add_log("系统初始化完成 - 产品种类: {}, 中转站库位: {}".format(
            self.product_types_count, self.transfer_station_size))

    """初始化产品类型和颜色"""
    def _init_product_types(self) -> None:
        self.state["product_types"] = []
        self.state["product_colors"] = {}

        # 生成产品类型标识 (A, B, C, ..., Z, AA, AB, ...)
        for i in range(self.product_types_count):
            label = ''
            num = i

            while True:
                remainder = num % 26
                label = chr(65 + remainder) + label
                num = num // 26 - 1
                if num < 0:
                    break

            self.state["product_types"].append(label)

            # 生成独特的颜色
            hue = (i * (360 / self.product_types_count)) % 360
            self.state["product_colors"][label] = f"hsl({hue}, 70%, 50%)"

    """添加操作日志"""
    def _add_log(self, message: str) -> None:
        now = datetime.now()
        time_string = now.strftime("%H:%M:%S")

        log_entry = {"time": time_string, "message": message}
        self.state["logs"].insert(0, log_entry)  # 插入到第一条位置

        # 限制日志数量为50条
        if len(self.state["logs"]) > 50:
            self.state["logs"].pop()  # 移除最后一条

    """生产3个产品（根据当前模式随机或顺序生成）"""
    def produce_products(self) -> Dict[str, Any]:
        if self.state["is_re_sorting"]:
            self._add_log("正在重新分拣中，暂时无法生产新产品")
            return self.get_state()

        # 清空当前生产区
        self.state["production"] = []

        # 根据生成模式生产3个产品
        for _ in range(3):
            if self.state["product_generation_mode"] == "random":
                # 随机生成模式
                random_index = random.randint(
                    0, len(self.state["product_types"]) - 1)
                product = self.state["product_types"][random_index]
            else:
                # 顺序生成模式
                product = self.state["product_types"][self.state["sequence_index"]]
                self.state["sequence_index"] = (self.state["sequence_index"] + 1) % len(self.state["product_types"])

            self.state["production"].append(product)

        self._add_log(f"生产了新产品: {', '.join(self.state['production'])}")
        return self.get_state()

    def toggle_product_generation_mode(self) -> Dict[str, Any]:
        """切换产品生成模式（随机生成 <-> 顺序生成）"""
        if self.state["product_generation_mode"] == "random":
            self.state["product_generation_mode"] = "sequence"
            self.state["sequence_index"] = 0  # 重置顺序索引
            self._add_log("产品生成模式已切换为：顺序生成")
        else:
            self.state["product_generation_mode"] = "random"
            self._add_log("产品生成模式已切换为：随机生成")

        return self.get_state()

    def transfer_to_production_AGV1(self) -> Dict[str, Any]:
        """将生产的产品转移到产线AGV1"""
        if not self.state["production"]:
            self._add_log("没有待转移的产品")
            return self.get_state()

        # 将生产的产品转移到产线AGV1
        self.state["production_AGV1"] = self.state["production"].copy()
        self.state["production"] = []

        self._add_log(
            f"产品已转移到产线AGV1: {', '.join(self.state['production_AGV1'])}")
        return self.get_state()

    def production_AGV1_to_sorting_station(self) -> Dict[str, Any]:
        """将生产的产品转移到分拣台"""
        if not self.state["production_AGV1"]:
            self._add_log("没有待转移的产品")
            return self.get_state()

        # 将生产的产品转移到分拣台
        self.state["sorting_station"] = self.state["production_AGV1"].copy()
        self.state["production_AGV1"] = []

        self._add_log(f"产品已转移到分拣台: {', '.join(self.state['sorting_station'])}")
        return self.get_state()

    def transfer_station_to_sorting_AGV(self) -> Dict[str, Any]:
        """将分拣台的产品转移到分拣AGV"""
        if not self.state["sorting_station"]:
            self._add_log("分拣台为空，无法转移产品")
            return self.get_state()

        # 将分拣台的产品转移到分拣AGV
        self.state["sorting_AGV"] = self.state["sorting_station"].copy()
        self.state["sorting_station"] = []

        self._add_log(f"产品已转移到分拣AGV: {self.state['sorting_AGV'][0],self.state['sorting_AGV'][1],self.state['sorting_AGV'][2]}")
        return self.get_state()

    def sorting_AGV_to_flip_station(self) -> Dict[str, Any]:
        """将分拣AGV的产品转移到翻转台"""
        if not self.state["sorting_AGV"]:
            self._add_log("分拣AGV为空，无法转移产品")
            return self.get_state()

        # 将分拣台的产品转移到翻转台
        self.state["flip_station"] = self.state["sorting_AGV"].copy()
        self.state["sorting_AGV"] = []

        self._add_log(f"产品已转移到翻转台: {', '.join(self.state['flip_station'])}")
        return self.get_state()

    def flip_station_to_flip_AGV(self) -> Dict[str, Any]:
        """将翻转台的产品转移到翻转AGV"""
        if not self.state["flip_station"]:
            self._add_log("翻转台为空，无法转移产品")
            return self.get_state()

        # 将翻转台的产品转移到翻转AGV
        self.state["flip_AGV"] = self.state["flip_station"].copy()
        self.state["flip_station"] = []

        self._add_log(f"产品已转移到翻转AGV: {', '.join(self.state['flip_AGV'])}")
        return self.get_state()

    def sorting_AGV_to_transfer_station(self) -> Dict[str, Any]:
        """将分拣AGV的产品转移到中转站"""
        if not self.state["sorting_AGV"]:
            self._add_log("分拣AGV为空，无法转移产品")
            return self.get_state()

        if self.state["is_re_sorting"]:
            self._add_log("正在重新分拣中，暂时无法转移产品")
            return self.get_state()

        # 判断是否满足三个相同设备 进行转移
        is_three_same, index = self._check_is_three_same()

        # 处理每个产品，使用智能放置算法
        for i, product in enumerate(self.state["sorting_AGV"]):
            # 如果产品以及被移除,跳过本次循环
            if product is None:
                continue
            # 如果产品是三个相同设备中的一个, 跳过本次循环
            if index[i] == 1 and self.state["flip_station"] == []:
                continue
            # 寻找最佳位置
            best_position = self._find_best_position(product)
            if best_position != -1:
                self.state["transfer_station"][best_position] = product
                self._add_log(f"产品 {product} 已放置到中转站位置 {best_position + 1}")
                # 从sorting_AGV中移除已处理的产品
                self.state["sorting_AGV"][i] = None
                # 三个全部放置后 , 清空分拣台
                if self.state["sorting_AGV"] == [None,None,None]:
                    self.state["sorting_AGV"] = []
                return self.get_state()
            else:
                self._add_log(f"中转站已满，无法放置产品 {product}")

                # 优先检查 分拣台 是否有 空位置
                for index1,product2 in enumerate(self.state["sorting_station"]):
                    if product2 is None and self.state["sorting_AGV"] != []:
                        self.state["sorting_station"][index1] = product
                        self.state["sorting_AGV"][i] = None
                        return self.get_state()
                    else:
                        continue

                sum_station = self.state["sorting_AGV"] + self.state["transfer_station"] + self.state["sorting_station"]
                # 检查 合并 的产品满足三个 但非连续
                for i, product3 in enumerate(sum_station):
                    if product3 and sum_station.count(product3) >= 3 and i > 2:
                        # 产品转移到分拣AGV
                        if self.state["sorting_AGV"][0] == None:
                            self.state["sorting_AGV"][0] = product3
                        elif self.state["sorting_AGV"][1] == None:
                            self.state["sorting_AGV"][1] = product3
                        elif self.state["sorting_AGV"][2] == None:
                            self.state["sorting_AGV"][2] = product3
                        else:
                            self._add_log(f"分拣AGV已满，无法放置产品 {product3}")
                            return self.get_state()

                        # 清空对应的库位
                        if i < len(self.state["sorting_AGV"]):
                            self.state["sorting_AGV"][i] = None
                        elif i < len(self.state["sorting_station"]) + len(self.state["transfer_station"]):
                            self.state["transfer_station"][i - len(self.state["sorting_station"])] = None
                        else:
                            self.state["sorting_station"][i - len(self.state["sorting_AGV"]) - len(self.state["transfer_station"])] = None

                        return self.get_state()

                return self.get_state()

        if is_three_same:
            self._add_log(f"存在产品满足翻转条件,进行翻转转移")

            # 从AGV获取产品信息（简化版）
            AGV_product = next((product for i, product in enumerate(self.state["sorting_AGV"]) if index[i] == 1 and product is not None), None)

            if AGV_product:
                # 寻找中转站中满足条件的产品
                for i, product in enumerate(self.state["transfer_station"]):
                    if product == AGV_product:
                        self.state["transfer_station"][i] = None
                        # 找到第一个空的位置并放置产品
                        empty_index = next((i for i, val in enumerate(index) if val == -1), None)
                        if empty_index is not None:
                            self.state["sorting_AGV"][empty_index] = product
                            self._add_log(f"产品 {product} 已从中转站转移到分拣AGV")
                            return self.get_state()
                for i, product in enumerate(self.state["sorting_station"]):
                    if product == AGV_product:
                        self.state["sorting_station"][i] = None
                        # 找到第一个空的位置并放置产品
                        empty_index = next((i for i, val in enumerate(index) if val == -1), None)
                        if empty_index is not None:
                            self.state["sorting_AGV"][empty_index] = product
                            self._add_log(f"产品 {product} 已从分拣台转移到分拣AGV")
                            return self.get_state()

        # 清空分拣台
        if self.state["sorting_AGV"] == [None,None,None]:
            self.state["sorting_AGV"] = []

        return self.get_state()

    def _check_is_three_same(self):
        """检查是否满足三个相同设备"""
        # 全部产品相同
        if len(set(self.state["sorting_AGV"])) == 1 and self.state["sorting_AGV"][0] != None:
            return True, [1,1,1]
        # 全部是空位置
        if len(set(self.state["sorting_AGV"])) == 1 and self.state["sorting_AGV"][0] == None:
            return False, [-1,-1,-1]

        list_all = self.state["sorting_AGV"] + self.state["transfer_station"] + self.state["sorting_station"]
        return_data = []
        for product in self.state["sorting_AGV"]:
            if product is None:
                return_data.append(-1)
                continue
            if list_all.count(product) >= 3:
                return_data.append(1)
                continue
            if list_all.count(product) < 3:
                return_data.append(0)
                continue

        # 满足直接搬运至翻转台  理论不会执行 前面已经被执行返回
        if return_data.count(1) == 3 and len(set(self.state["sorting_AGV"])) == 1:
            return True, return_data

        # 全部满足三个数量
        if return_data.count(1) == 3 and len(set(self.state["sorting_AGV"])) != 1:
            # 三个产品均不同
            if len(set(self.state["sorting_AGV"])) == 3:
                return True, [1,0,0]
            # 产品种类为2+1
            if self.state["sorting_AGV"][0] == self.state["sorting_AGV"][1]:
                return True, [1,1,0]
            if self.state["sorting_AGV"][0] == self.state["sorting_AGV"][2]:
                return True, [1,0,1]
            if self.state["sorting_AGV"][1] == self.state["sorting_AGV"][2]:
                return True, [0,1,1]

        # 部分满足三个数量 产品种类为2+1
        if return_data.count(1) == 2 and len(set(self.state["sorting_AGV"])) == 2:
            if self.state["sorting_AGV"][0] == self.state["sorting_AGV"][1]:
                if self.state["sorting_AGV"][2] == None:
                    return True, [1,1,-1]
                else:
                    return True, [1,1,0]
            if self.state["sorting_AGV"][0] == self.state["sorting_AGV"][2]:
                if self.state["sorting_AGV"][1] == None:
                    return True, [1,-1,1]
                else:
                    return True, [1,0,1]
            if self.state["sorting_AGV"][1] == self.state["sorting_AGV"][2]:
                if self.state["sorting_AGV"][0] == None:
                    return True, [-1,1,1]
                else:
                    return True, [0,1,1]

        # 部分满足三个数量 产品种类为1+1+1
        if return_data.count(1) == 2 and len(set(self.state["sorting_AGV"])) == 3:
            return True, [0,0,1]

        if return_data.count(1) != 0:
            return True, return_data
        else:
            return False, return_data

    def _find_best_position(self, product: str) -> int:
        """寻找最佳的产品放置位置"""
        best_position = -1
        best_score = -1

        # 评估每个空位的放置价值
        for index, cell in enumerate(self.state["transfer_station"]):
            if cell is None:
                # 计算这个位置的分数，分数越高越适合放置当前产品
                score = self._calculate_position_score(index, product)

                # 如果找到更好的位置，更新最佳位置
                if score > best_score:
                    best_score = score
                    best_position = index

        return best_position

    def _calculate_position_score(self, position: int, product: str) -> int:
        """计算位置分数，评估放置产品的价值"""
        score = 0

        # 1. 检查是否可以形成三连（最高权重）
        if position > 0 and position < len(self.state["transfer_station"]) - 1 and \
           self.state["transfer_station"][position - 1] == product and \
           self.state["transfer_station"][position + 1] == product:
            score += 200  # 可以形成三连，大幅加分

        # 2. 检查相邻位置是否有相同产品（次高权重）
        # 左侧相邻
        if position > 0 and self.state["transfer_station"][position - 1] == product:
            score += 100  # 相同产品相邻加分
        # 右侧相邻
        if position < len(self.state["transfer_station"]) - 1 and self.state["transfer_station"][position + 1] == product:
            score += 100  # 相同产品相邻加分

        # 3. 检查附近是否有相同产品集群（中等权重）
        cluster_bonus = self._calculate_cluster_bonus(position, product)
        score += cluster_bonus

        # 4. 检查该位置周围的空位，优先选择有连续空位的位置（便于未来放置）
        empty_space_bonus = self._calculate_empty_space_bonus(position)
        score += empty_space_bonus

        # 5. 基本分：确保空位都有基础分值
        score += 10

        return score

    def _calculate_cluster_bonus(self, position: int, product: str) -> int:
        """计算集群奖励分"""
        bonus = 0
        cluster_range = 4  # 检查周围4个位置

        # 计算左侧相同产品数量
        for i in range(1, cluster_range + 1):
            if position - i >= 0 and self.state["transfer_station"][position - i] == product:
                bonus += (cluster_range - i + 1) * 10  # 越近加分越多
            elif position - i >= 0 and self.state["transfer_station"][position - i] is not None:
                break  # 遇到不同产品则停止计数

        # 计算右侧相同产品数量
        for i in range(1, cluster_range + 1):
            if position + i < len(self.state["transfer_station"]) and self.state["transfer_station"][position + i] == product:
                bonus += (cluster_range - i + 1) * 10  # 越近加分越多
            elif position + i < len(self.state["transfer_station"]) and self.state["transfer_station"][position + i] is not None:
                break  # 遇到不同产品则停止计数

        return bonus

    def _calculate_empty_space_bonus(self, position: int) -> int:
        """计算空位奖励分（优先选择有连续空位的位置）"""
        bonus = 0

        # 检查左侧连续空位数
        left_empty_count = 0
        for i in range(1, 4):
            if position - i >= 0 and self.state["transfer_station"][position - i] is None:
                left_empty_count += 1
            else:
                break

        # 检查右侧连续空位数
        right_empty_count = 0
        for i in range(1, 4):
            if position + i < len(self.state["transfer_station"]) and self.state["transfer_station"][position + i] is None:
                right_empty_count += 1
            else:
                break

        # 计算连续空位的总长度
        total_empty_length = left_empty_count + right_empty_count + 1
        bonus += total_empty_length * 5  # 每连续一个空位加5分

        return bonus

    def check_shipment_possible(self) -> bool:
        """检查是否有产品可以出库"""
        # 检查中转站满料 部分出料
        numb = 0
        for product in self.state["transfer_station"]:
            if product is None:
                numb += 1
        if numb <= 2:
            sum_station = self.state["sorting_station"] + self.state["transfer_station"]
            # 检查 合并 的产品满足三个 但非连续
            for i, product in enumerate(sum_station):
                if product and sum_station.count(product) >= 3:
                    # 产品转移到分拣AGV
                    self.state["sorting_AGV"].append(product)
                    self.state["sorting_AGV"].append(None)
                    self.state["sorting_AGV"].append(None)
                    # 清空对应的库位
                    if i < len(self.state["sorting_station"]):
                        self.state["sorting_station"][i] = None
                    else:
                        self.state["transfer_station"][i - len(self.state["sorting_station"])] = None
                    return True

        # 检查连续三个相同的产品
        for i in range(len(self.state["transfer_station"]) - 2):
            if (self.state["transfer_station"][i] and
                self.state["transfer_station"][i] == self.state["transfer_station"][i + 1] and
                    self.state["transfer_station"][i] == self.state["transfer_station"][i + 2]):

                # 产品转移到分拣AGV
                self.state["sorting_AGV"].append(self.state["transfer_station"][i])
                self.state["sorting_AGV"].append(self.state["transfer_station"][i + 1])
                self.state["sorting_AGV"].append(self.state["transfer_station"][i + 2])

                # 清空对应的库位
                self.state["transfer_station"][i] = None
                self.state["transfer_station"][i + 1] = None
                self.state["transfer_station"][i + 2] = None

                # self._add_log(f"产品 {self.state["sorting_AGV"][0]} 优先分拣")
                return True

        # 检查中转站的产品满足三个 但非连续
        for i, product in enumerate(self.state["transfer_station"]):
            if product and self.state["transfer_station"].count(product) >= 3:
                # 产品转移到分拣AGV
                self.state["sorting_AGV"].append(product)
                self.state["sorting_AGV"].append(None)
                self.state["sorting_AGV"].append(None)
                # 清空对应的库位
                self.state["transfer_station"][i] = None
                return True

        return False

    def output_products(self) -> None:
        """产品出库"""
        if not self.state["flip_AGV"]:
            return

        if len(set(self.state["flip_AGV"])) == 1 and self.state["flip_AGV"][0]:
            product = self.state["flip_AGV"][0]
            self.state["shipped_products"].append(product)
            self.state["flip_AGV"] = None
            self._add_log(f"产品 {product} 出库成功")

    def reset_simulation(self) -> Dict[str, Any]:
        """重置模拟系统"""
        self.state = {
            "product_types": self.state["product_types"],
            "product_colors": self.state["product_colors"],
            "production": [],
            "production_AGV1": [],
            "sorting_station": [],
            "sorting_AGV": [],
            "transfer_station": [None] * self.transfer_station_size,
            "flip_station": [],  # 翻转台的产品
            "flip_AGV": [],
            "shipped_products": [],
            "logs": [],
            "is_auto_running": False,
            "is_re_sorting": False,
            "re_sort_count": 0,
            "product_generation_mode": self.state["product_generation_mode"],  # 产品生成模式: random(随机) 或 sequence(顺序)
            "sequence_index": 0,
        }

        self._add_log("模拟系统已重置")
        return self.get_state()

    def toggle_auto_run(self) -> Dict[str, Any]:
        """切换自动运行状态"""
        self.state["is_auto_running"] = not self.state["is_auto_running"]
        status = "启动" if self.state["is_auto_running"] else "停止"
        self._add_log(f"自动运行已{status}")
        return self.get_state()

    def step_run(self) -> Dict[str, Any]:
        """单步运行模拟"""
        if self.state["is_re_sorting"]:
            self._add_log("正在重新分拣中，无法进行单步运行")
            return self.get_state()

        # 如果生产区为空，生产产品
        if not self.state["production"]:
            self.produce_products()

        # 如果产线AGV为空，将产品从生产区转移到产线AGV
        elif not self.state["production_AGV1"]:
            self.transfer_to_production_AGV1()

        # 如果分拣台为空，将产品从产线AGV转移到分拣台
        elif not self.state["sorting_station"]:
            self.production_AGV1_to_sorting_station()

        # 如果分拣AGV为空，将产品从转移到分拣AGV
        elif not self.state["sorting_AGV"]:
            # 优先执行的分拣任务
            if self.check_shipment_possible() == False:
                self.transfer_station_to_sorting_AGV()

        # 如果翻转AGV为空，将产品从翻转台转移到翻转AGV
        elif not self.state["flip_AGV"] and self.state["flip_station"]:
            self.flip_station_to_flip_AGV()

        # 否则将产品从分拣台转移到中转站
        else:
            # 检查是否可以出库
            self.output_products()
            # 检查是否可以分拣
            is_three_same, index = self._check_is_three_same()
            print(is_three_same, index)
            if is_three_same and index == [1,1,1] and not self.state["flip_station"]:
                self.sorting_AGV_to_flip_station()
            else:
                self.sorting_AGV_to_transfer_station()

        return self.get_state()

    def get_state(self) -> Dict[str, Any]:
        """获取当前系统状态"""
        # 统计每种产品的数量
        product_stats = {}
        for product in self.state["product_types"]:
            # 安全地统计数量，确保无法统计时自增0
            numn = 0
            try:
                numn += self.state["production"].count(product) if self.state["production"] is not None else 0
                numn += self.state["production_AGV1"].count(product) if self.state["production_AGV1"] is not None else 0
                # 移除对不存在的production_AGV2的访问
                numn += self.state["sorting_station"].count(product) if self.state["sorting_station"] is not None else 0
                numn += self.state["sorting_AGV"].count(product) if self.state["sorting_AGV"] is not None else 0
                in_transfer_station = self.state["transfer_station"].count(product) if self.state["transfer_station"] is not None else 0
                numn += self.state["flip_station"].count(product) if self.state["flip_station"] is not None else 0
                numn += self.state["flip_AGV"].count(product) if self.state["flip_AGV"] is not None else 0
                shipped = (self.state["shipped_products"].count(product) if self.state["shipped_products"] is not None else 0) * 3
            except Exception:
                # 发生任何异常时，保持数量为0
                numn = 0
                in_transfer_station = 0
                shipped = 0
            total = numn + shipped + in_transfer_station

            product_stats[product] = {
                "in_transfer_station": in_transfer_station,
                "shipped": shipped,
                "total": total,
                "color": self.state["product_colors"][product]
            }

        return {
            "production": self.state["production"],
            "production_AGV1": self.state["production_AGV1"],  # 产线AGV1产品
            "sorting_station": self.state["sorting_station"],
            "sorting_AGV": self.state["sorting_AGV"],  # 分拣AGV产品
            "transfer_station": self.state["transfer_station"],
            "flip_station": self.state["flip_station"],  # 翻转台的产品
            "flip_AGV": self.state["flip_AGV"],
            "shipped_products": self.state["shipped_products"],
            "logs": self.state["logs"],
            "is_auto_running": self.state["is_auto_running"],
            "is_re_sorting": self.state["is_re_sorting"],
            "re_sort_count": self.state["re_sort_count"],
            "product_stats": product_stats,
            "empty_slots": self.state["transfer_station"].count(None),
            "product_generation_mode": self.state["product_generation_mode"],  # 添加产品生成模式
            "station_size": self.transfer_station_size,
            "product_types_count": self.product_types_count,
        }

    def change_station_size(self, new_size: int) -> Dict[str, Any]:
        """改变中转站库位数量"""
        if new_size < 6 or new_size > 30:
            self._add_log(f"中转站库位数量必须在6-30之间，当前设置为{new_size}")
            return self.get_state()

        # 保存当前产品
        current_products = [
            p for p in self.state["transfer_station"] if p is not None]

        # 调整中转站大小
        self.transfer_station_size = new_size
        self.state["transfer_station"] = [None] * new_size

        # 重新放置产品
        for i, product in enumerate(current_products):
            if i < new_size:
                self.state["transfer_station"][i] = product
            else:
                # 无法放置的产品将丢失
                self._add_log(f"调整库位大小时，产品 {product} 无法放置，已丢失")

        self._add_log(f"中转站库位数量已调整为{new_size}")
        return self.get_state()

    def change_product_types_count(self, new_count: int) -> Dict[str, Any]:
        """改变产品种类数量"""
        if new_count < 2 or new_count > 20:
            self._add_log(f"产品种类数量必须在2-20之间，当前设置为{new_count}")
            return self.get_state()

        # 更新产品种类数量
        self.product_types_count = new_count

        # 重新初始化产品类型
        self._init_product_types()

        self._add_log(f"产品种类数量已调整为{new_count}")
        return self.get_state()


# 全局模拟实例
_simulation_instance = None


def get_simulation() -> SortingSimulation:
    """获取模拟实例"""
    global _simulation_instance
    if _simulation_instance is None:
        _simulation_instance = SortingSimulation()
    return _simulation_instance
